home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Libraries / Mercutio 1.2b20 / Sample Code / Mercutio Test App.p < prev    next >
Encoding:
Text File  |  1994-09-29  |  11.6 KB  |  424 lines  |  [TEXT/PJMM]

  1. PROGRAM TestMDEFApp;
  2.     USES
  3.         MercutioAPI, PopupDialog;
  4.     CONST
  5.         lwrX = 120;
  6.         lwrV = 118;
  7.         lwrC = 99;
  8.  
  9.         appleMenuID = 300;        { Resource ID of the Apple menu }
  10.         fileMenuID = 301;        { Resource ID of the File menu }
  11.         editMenuID = 302;        { Resource ID of the Edit menu }
  12.         modifiersMenuID = 303;
  13.         iconsMenuID = 304;
  14.         nonPrintingMenuID = 305;
  15.         callbackMenuID = 306;
  16.         colorMenuID = 307;
  17.  
  18.         firstMenu = 300;        { Res ID of first menu in menu bar }
  19.         lastMenu = 307;        { Res ID of last menu in menu bar }
  20.  
  21.         popupMenuID = 1;
  22.         firstHierMenu = 1;
  23.         lastHierMenu = 1;
  24.  
  25.         kICONSize = 32;
  26.         kSICNSize = 16;
  27.         svAllLargeData = $000000ff;
  28.         svAllSmallData = $0000ff00;
  29.  
  30.         addFolderIconID = 262;
  31.         addFoldersIconID = 263;
  32.         addFileIconID = 264;
  33.         addFilesIconID = 265;
  34.  
  35.     TYPE
  36.         IconSelectorValue = LONGINT;
  37.  
  38.     VAR
  39.         Finished: Boolean;                { Set to true when were done    }
  40.  
  41.         normalMenus: ARRAY[firstMenu..lastMenu] OF MenuHandle; { The menus in menu bar    }
  42.         HierMenus: ARRAY[firstHierMenu..lastHierMenu] OF MenuHandle; { The hidden menus    }
  43.  
  44.         hMDEF: handle;                    { required for PowerMenuKey }
  45.  
  46.  
  47.  
  48.  
  49.     PROCEDURE ToggleItemCheck (theMenu: MenuHandle; item: Integer);
  50.         VAR
  51.             curMark: char;
  52.     BEGIN
  53.         GetItemMark(theMenu, item, curMark);
  54.         IF curMark = chr(noMark) THEN
  55.             CheckItem(theMenu, item, true) {check it on in menu}
  56.         ELSE
  57.             CheckItem(theMenu, item, false); {check it off in menu}
  58.     END;
  59.  
  60. {------------------------- process the menu selection --------------------------}
  61.  
  62.     PROCEDURE ProcessMenu (CodeWord: LongInt);
  63.  
  64.         VAR
  65.             menuNum: Integer;                { Res ID of the menu Selected    }
  66.             itemNum: Integer;                { The item number selected    }
  67.             nameHolder: str255;            { the name of the desk acc.    }
  68.             dummy: Integer;                { just a dummy            }
  69.             AboutRecord: DialogRecord;    { the actual object        }
  70.             AboutDlog: DialogPtr;            { a pointer to my dialog    }
  71.             tempStr: str255;
  72.     BEGIN
  73.         menuNum := HiWord(CodeWord);    { get the menu number        }
  74.         itemNum := LoWord(CodeWord);    { get the item number        }
  75.         IF itemNum > 0 THEN            { ok to handle the menu?    }
  76.             BEGIN
  77.                 CASE MenuNum OF
  78.                     appleMenuID: 
  79.                         CASE ItemNum OF
  80.                             1: 
  81.                                 BEGIN
  82.                                     AboutDlog := GetNewDialog(3000, @AboutRecord, Pointer(-1));
  83.                                     ModalDialog(NIL, dummy);
  84.                                     CloseDialog(AboutDlog);
  85.                                 END;
  86.                             2: 
  87.                                 BEGIN
  88.                                 END;
  89.                             OTHERWISE
  90.                                 BEGIN
  91.                                     GetItem(normalMenus[appleMenuID], ItemNum, NameHolder);
  92.                                     dummy := OpenDeskAcc(NameHolder);
  93.                                 END;
  94.                         END;
  95.                     fileMenuID: 
  96.                         CASE itemNum OF
  97.                             1: 
  98.                                 doPopupDialog(hierMenus[popupMenuID]);
  99.                             3: 
  100.                                 Finished := true;
  101.                             OTHERWISE
  102.                                 ToggleItemCheck(normalMenus[MenuNum], ItemNum);
  103.                         END;
  104.                     editMenuID: 
  105.                         IF NOT SystemEdit(ItemNum - 1) THEN
  106.                             BEGIN        {we don't support any editing}
  107.                                 ToggleItemCheck(normalMenus[MenuNum], ItemNum);
  108.                             END;
  109.                     firstHierMenu..lastHierMenu: 
  110.                         IF ItemNum <> 0 THEN
  111.                             ToggleItemCheck(hierMenus[MenuNum], ItemNum);
  112.                     modifiersMenuID..lastMenu: 
  113.                         IF ItemNum <> 0 THEN
  114.                             ToggleItemCheck(normalMenus[MenuNum], ItemNum);
  115.                     OTHERWISE
  116.                         sysbeep(1);
  117.                 END;                        { of case menuNum of        }
  118.             END;                            { of if CodeWord...        }
  119.         HiliteMenu(0);
  120.     END;                                { of process menu        }
  121.  
  122. {------------------------------- Main Event loop -------------------------------}
  123.  
  124.     PROCEDURE MainEventLoop;
  125.         VAR
  126.             Event: EventRecord;            { Filled by Get next event    }
  127.             windowLoc: integer;            { the mouse location        }
  128.             mouseLoc: point;                { the area it was in        }
  129.             theWindow: WindowPtr;            { Dummy,cause we have no windows}
  130.             matchedItem: longint;
  131.     BEGIN
  132.         REPEAT                            { do this until we selected quit}
  133.             SystemTask;                    { Take care of desk accessories    }
  134.             IF GetNextEvent(everyEvent, Event) THEN    { if there was an event... then    }
  135.                 CASE event.what OF            { case out on the event type    }
  136.                     mouseDown:                { we had a mouse-down event    }
  137.                         BEGIN
  138.                             mouseLoc := Event.where;    { wheres the pesky mouse    }
  139.                             windowLoc := FindWindow(mouseLoc, theWindow); { find out where }
  140.                             CASE windowLoc OF    { now case on the location    }
  141.                                 inMenuBar: 
  142.                                     ProcessMenu(MenuSelect(MouseLoc)); { Handle the selection    }
  143.                                 inSysWindow: 
  144.                                     SystemClick(Event, theWindow); {It was in a desk acc    }
  145.                                 OTHERWISE
  146.                             END;
  147.                         END;
  148.                     keyDown, AutoKey:            { we had the user hit a key    }
  149.                         BEGIN
  150.                             matchedItem := MDEF_MenuKey(Event.message, Event.modifiers, normalMenus[modifiersMenuID]);
  151.                             writeln('menu:', hiWord(matchedItem) : 1, ', item: ', loWord(matchedItem));
  152.                             ProcessMenu(matchedItem);
  153.                         END;
  154.                     OTHERWISE
  155.                 END;            { of case event.what...        }
  156.         UNTIL (Finished);    { end of repeat statement    }
  157.     END;                    { of main event loop        }
  158.  
  159.  
  160.     PROCEDURE getModifiers (VAR theMods: integer);
  161.         TYPE
  162.             intAsMods = PACKED RECORD
  163.                     b5, b6, b7: boolean;
  164.                     control: boolean;
  165.                     option: boolean;
  166.                     capsLock: boolean;
  167.                     shift: boolean;
  168.                     command: boolean;
  169.                     eventType: char;
  170.                 END;
  171.         VAR
  172.             k: keyMap;
  173.     BEGIN
  174.         theMods := 0;
  175.         GetKeys(k);
  176.         WITH intAsMods(theMods) DO
  177.             BEGIN
  178.                 control := k[$3B];
  179.                 shift := k[$38];
  180.                 option := k[$3A];
  181.                 command := k[$37];
  182.                 capsLock := k[$39];
  183.             END;
  184.     END;
  185.  
  186.  
  187.     PROCEDURE MyGetItemInfo (menuID: integer; previousModifiers: integer; VAR itemData: RichItemData);
  188.     { This routine is used by the Callback menu to demonstrate the }
  189.     { Mercutio callback mechanism. This routine is called for every }
  190.     { item in the menu flagged as a "callback item" (in our case, }
  191.     { with the Outline style bit). }
  192.     {}
  193.     { In this example, we check the Shift and Option keys to }
  194.     { determine what the text and icon of the menu item should }
  195.     { be. }
  196.     {}
  197.     { Note the "Dirty" parameter; if we don't change anything}
  198.     { in the menuItem, this parameter should be false to}
  199.     { avoid unnecessary redrawing (and flicker).}
  200.     {}
  201.  
  202.         VAR
  203.             theErr: osErr;
  204.             modifiers: integer;
  205.             tickStr: str255;
  206.     BEGIN
  207.         getModifiers(modifiers);    { get the user's current modifiers }
  208.         theErr := noErr;
  209.  
  210.         IF itemData.itemID = 37 THEN
  211.             CASE itemData.cbMsg OF
  212.                 cbBasicDataOnlyMsg: 
  213.                     BEGIN
  214.                         IF (BitAnd(modifiers, shiftKey) > 0) THEN
  215.                             BEGIN
  216.                                 itemData.flags.shiftKey := true;
  217.                                 IF (BitAnd(modifiers, optionKey) > 0) THEN
  218.                                     BEGIN
  219.                                         itemData.itemStr := 'Add Folders…';
  220.                                         itemData.flags.optionKey := true;
  221.                                     END
  222.                                 ELSE
  223.                                     BEGIN
  224.                                         itemData.itemStr := 'Add Folder…';
  225.                                     END;
  226.                             END
  227.                         ELSE
  228.                             BEGIN
  229.                                 IF (BitAnd(modifiers, optionKey) > 0) THEN
  230.                                     BEGIN
  231.                                         itemData.itemStr := 'Add Files…';
  232.                                         itemData.flags.optionKey := true;
  233.                                     END
  234.                                 ELSE
  235.                                     BEGIN
  236.                                         itemData.itemStr := 'Add File…';
  237.                                     END
  238.                             END;
  239.                         itemData.flags.hasIcon := true;
  240.                         itemData.flags.changedByCallback := (modifiers <> previousModifiers);
  241.                     END;
  242.                 cbIconOnlyMsg: 
  243.                     BEGIN
  244.                         IF (BitAnd(modifiers, shiftKey) > 0) THEN
  245.                             IF (BitAnd(modifiers, optionKey) > 0) THEN
  246.                                 itemData.hIcon := handle(GetCIcon(AddFoldersIconID))
  247.                             ELSE
  248.                                 itemData.hIcon := handle(GetCIcon(AddFolderIconID))
  249.                         ELSE
  250.                             BEGIN
  251.                                 IF (BitAnd(modifiers, optionKey) > 0) THEN
  252.                                     itemData.hIcon := handle(GetCIcon(AddFilesIconID))
  253.                                 ELSE
  254.                                     itemData.hIcon := handle(GetCIcon(AddFileIconID));
  255.                             END;
  256.                         itemData.flags.hasIcon := true;
  257.                         itemData.iconType := 'cicn';
  258.                         itemData.flags.changedByCallback := (modifiers <> previousModifiers);
  259.                     END;
  260.                 OTHERWISE
  261.                     BEGIN
  262.                     END;
  263.             END
  264.         ELSE IF itemData.itemID = 38 THEN
  265.             BEGIN
  266.                 CASE itemData.cbMsg OF
  267.                     cbBasicDataOnlyMsg: 
  268.                         BEGIN
  269.                             NumToString(TickCount, tickStr);
  270.                             itemData.itemStr := concat('Ticks: ', tickStr);
  271.                             itemData.flags.changedByCallback := true;
  272.                         END;
  273.                     cbIconOnlyMsg: 
  274.                         BEGIN
  275.                         END;
  276.                 END;
  277.             END;
  278.     END;
  279.  
  280. {------------------------------ SetUp Everything -------------------------------}
  281.  
  282.     PROCEDURE SetUpThings;
  283.         TYPE
  284.             ShortPtr = ^integer;
  285.             LongPtr = ^longint;
  286.         VAR
  287.             index: integer;                { used in a for loop        }
  288.             hRes: handle;
  289.             dataPtr: ptr;
  290.  
  291.             prefs: MenuPrefsRec;
  292.     BEGIN
  293.  
  294.     { *** load and install the menus *** }
  295.         FOR index := firstMenu TO lastMenu DO    { loop for all menus in menu bar}
  296.             BEGIN
  297.                 normalMenus[index] := GetMenu(index);    { Get the next menu        }
  298.                 IF index = appleMenuID THEN
  299.                     AddResMenu(normalMenus[appleMenuID], 'DRVR');    { Add desk accessories        }
  300.                 InsertMenu(normalMenus[index], 0);
  301.                 CalcMenuSize(normalMenus[index]);
  302.             END;
  303.  
  304.         FOR index := firstHierMenu TO lastHierMenu DO
  305.             BEGIN
  306.                 hierMenus[index] := GetMenu(index);
  307.                 InsertMenu(hierMenus[index], -1);
  308.                 CalcMenuSize(hierMenus[index]);
  309.             END;
  310.  
  311.  
  312.     { *** setup the preferences for our menus *** }
  313.     { This is where we determine which style bits are mapped to }
  314.     { MDEF features. Most of the menus use Mercutio's default }
  315.     { settings. These menus are the exceptions. }
  316.     {}
  317.     { Feel free to play with these settings and see how }
  318.     { the menus are affected.}
  319.     {}
  320.     { Note that we could have stored all this information in an}
  321.     { 'Xmnu' resource with the same ID as the menu, and avoided }
  322.     { the hassle of setting these preferences programmatically. }
  323.     { We do it this way to demonstrate the various features of}
  324.     { the MDEF. }
  325.  
  326.     { *** set up the Color menu *** }
  327.     {        1. the Color menu uses an 'Xmnu' resource }
  328.     {            to restore the Condense and Extend bits to their }
  329.     {           regular functions (as style bits), and sets the }
  330.     {           DEFAULT modifiers to Option-Command. This means }
  331.     {           that key equivalents in this Menu need the Command }
  332.     {           and Option keys held down, but all the style bits}
  333.     {           are still free to be used as such. }
  334.     {}
  335.         WITH prefs DO
  336.             BEGIN
  337.                 optionKeyFlag := [];
  338.                 shiftKeyFlag := [];
  339.                 cmdKeyFlag := [];
  340.                 controlKeyFlag := [];
  341.                 isDynamicFlag := [];
  342.                 forceNewGroupFlag := [];
  343.                 useCallbackFlag := [];
  344.                 requiredModifiers := cmdKey + optionKey;
  345.             END;
  346.         MDEF_SetMenuPrefs(normalMenus[colorMenuID], @prefs);
  347.  
  348.  
  349.  
  350.     { *** set up the Modifiers menu *** }
  351.     {}
  352.     {    2. the Modifiers menu demonstrates all four }
  353.     {      modifier keys in action. Thus, we need}
  354.     {      to use four style bits, which we }
  355.     {      select and store below.}
  356.     {}
  357.         WITH prefs DO
  358.             BEGIN
  359.                 optionKeyFlag := [underline];
  360.                 shiftKeyFlag := [extend];
  361.                 cmdKeyFlag := [bold];
  362.                 controlKeyFlag := [shadow];
  363.                 isDynamicFlag := [];
  364.                 forceNewGroupFlag := [];
  365.                 useCallbackFlag := [outline];
  366.                 requiredModifiers := 0;
  367.             END;
  368.         MDEF_SetMenuPrefs(normalMenus[modifiersMenuID], @prefs);
  369.  
  370.  
  371.  
  372.     { *** set up the Callback menu *** }
  373.     { Note that we can make this call regardless of what MDEF we are using, }
  374.     { because if an MDEF doesn't recognize a message (in our case, the }
  375.     { SetCallback message), it simply ignores it.}
  376.     {}
  377.         WITH prefs DO
  378.             BEGIN
  379.                 optionKeyFlag := [condense];
  380.                 shiftKeyFlag := [extend];
  381.                 cmdKeyFlag := [];
  382.                 controlKeyFlag := [];
  383.                 isDynamicFlag := [outline];
  384.                 forceNewGroupFlag := [italic];
  385.                 useCallbackFlag := [underline];
  386.                 requiredModifiers := cmdKey;
  387.             END;
  388.         MDEF_SetCallbackProc(normalMenus[callbackMenuID], @MyGetItemInfo);
  389.         MDEF_SetMenuPrefs(normalMenus[callbackMenuID], @prefs);
  390.  
  391.         DrawMenuBar;
  392.     END;
  393.  
  394.  
  395.  
  396.  
  397.  
  398.     PROCEDURE Cleanup;
  399.     { loop through all of the menus and release them from memory }
  400.         VAR
  401.             index: integer;
  402.     BEGIN
  403.         FOR index := firstMenu TO lastMenu DO    { loop for all menus in menu bar}
  404.             BEGIN
  405.                 DeleteMenu(index);
  406.                 ReleaseResource(handle(normalMenus[index]));
  407.             END;
  408.         FOR index := firstHierMenu TO lastHierMenu DO    { loop for all menus in menu bar}
  409.             BEGIN
  410.                 DeleteMenu(index);
  411.                 ReleaseResource(handle(hierMenus[index]));
  412.             END;
  413.     END;
  414.  
  415.  
  416. {------------------------------- Main Program Seg ------------------------------}
  417.  
  418. BEGIN
  419.     InitCursor;                { make the cursor an arrow    }
  420.     SetUpThings;
  421.     Finished := false;
  422.     MainEventLoop;
  423.     Cleanup;
  424. END.